package com.java8feature.java8action.chapter11;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @Author: yangzhiwei
 * @Date: 2021/6/15 16:51
 */
public class CompletableFutureTest {

    public double getPrice(String product) throws InterruptedException {
        return calculatePrice(product);
    }

    private double calculatePrice(String product) throws InterruptedException {
        Random r = new Random();
        int randNum =  r.nextInt(3);
        System.out.println(randNum);
        long startTime = System.currentTimeMillis();

        delay(randNum);
        System.out.println("get" + product + "Price Time ->" + (System.currentTimeMillis() - startTime));
        return r.nextDouble() * product.charAt(0) + product.charAt(1);
    }

    private void delay(Integer dalaySeconds) throws InterruptedException {
        if (dalaySeconds == null) {
           delay1SECNODS();
        } else {
           TimeUnit.SECONDS.sleep(dalaySeconds);
        }
    }

    private void delay1SECNODS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
    }

    public Map normalTest() throws InterruptedException {

        Map<String, Double> map = new HashMap<>();

        System.out.println("==================start========================");
        map.put("applePrice", getPrice("apple"));
        map.put("orangePrice", getPrice("orange"));
        System.out.println("====================end=========================");
        return map;
    }


    public Future<Double> getPriceAsync(String product) {
        CompletableFuture<Double>  futurePrice = new CompletableFuture<>();
        new Thread( () -> {
            double price = 0;
            try {
                price = calculatePrice(product);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            futurePrice.complete(price);
            }).start();

        return futurePrice;
    }

    public Map completableExceptionTest() throws InterruptedException, ExecutionException {

        Map<String, Double> map = new HashMap<>();

        System.out.println("==================AsynStart========================");
        Future<Double> future1 = getCompletableException("apple");
        Future<Double> future2 = getCompletableException("orange");
        System.out.println("====================AsynEnd=========================");

        System.out.println("==================AsynGetStart========================");
        map.put("applePrice", future1.get());
        map.put("orangePrice", future2.get());
        System.out.println("==================AsynGetEnd========================");
        return map;
    }

    public Future<Double> getCompletableException(String product) {
        CompletableFuture<Double>  futurePrice = new CompletableFuture<>();
        new Thread( () -> {
            double price = 0;
            try {
                price = calculatePrice(product);
                throw new RuntimeException("completable Exception");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            futurePrice.complete(price);
        }).start();

        return futurePrice;
    }

    public Map future1Test() throws InterruptedException, ExecutionException {

        Map<String, Double> map = new HashMap<>();

        System.out.println("==================AsynStart========================");
        Future<Double> future1 = getPriceAsync("apple");
        Future<Double> future2 = getPriceAsync("orange");
        System.out.println("====================AsynEnd=========================");

        System.out.println("==================AsynGetStart========================");
        map.put("applePrice", future1.get());
        map.put("orangePrice", future2.get());
        System.out.println("==================AsynGetEnd========================");

        // ******** 异常

        return map;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        CompletableFutureTest test = new CompletableFutureTest();
        Map res = test.normalTest();
        System.out.println(res);

        Map res2 = test.future1Test();

        Map res3 = test.completableExceptionTest();


    }
}
